#pragma once
// 并发执行申请 -封装ThreadCache的申请调用等操作

#include "Common.hpp"
#include "ThreadCache.hpp"
#include "PageCache.hpp"
#include "FixedLengthMemoryPool.hpp"

// 向线程缓存区申请内存
static void* ConcurrentAlloc(size_t size)
{
	if (size > MAX_BYTES)
	{
		size_t k = SizeClass::RoundUp(size);  // 先向上对齐
		PageCache::GetInstance()->_pageMtx.lock();
		span* myspan = PageCache::GetInstance()->NewSpan(k >> PAGE_SHIFT);
		myspan->_objSize = k;
		PageCache::GetInstance()->_pageMtx.unlock();

		void* ptr = (void*)(myspan->_pageld << PAGE_SHIFT);
		return ptr;
	}

	if (pTLSThreadCache == nullptr)
	{
		//pTLSThreadCache = new ThreadCache;  // 利用了TLS 每个线程拥有自己的一份线程内存池
		static FLMemoryPool<ThreadCache> threadPool;  // 使用定长内存池解决问题
		pTLSThreadCache = threadPool.New();
		//QiHai::LogMessage(QiHai::DEBUG, "%d, %p", std::this_thread::get_id(), pTLSThreadCache);
	}
	return pTLSThreadCache->Allocate(size);
}

// 面向线程缓存区进行释放内存
static void ConcurrentFree(void* ptr)
{
	assert(ptr);
	span* objSpan = PageCache::GetInstance()->MapObjectToSpan(ptr);  //  需要加锁的说
	size_t size = objSpan->_objSize;

	if (size > MAX_BYTES)
	{
		PageCache::GetInstance()->_pageMtx.lock();
		PageCache::GetInstance()->ReleaseSpanToPageCache(objSpan);
		PageCache::GetInstance()->_pageMtx.unlock();
	}
	else
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, size);
	}
}